package com.atguigu.gulimall.ware.service.impl;

import com.atguigu.common.constant.WareConstant;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.ware.dao.WareSkuDao;
import com.atguigu.gulimall.ware.entity.PurchaseDetailEntity;
import com.atguigu.gulimall.ware.entity.WareSkuEntity;
import com.atguigu.gulimall.ware.feign.ProductServiceFeign;
import com.atguigu.gulimall.ware.service.PurchaseDetailService;
import com.atguigu.gulimall.ware.service.WareSkuService;
import com.atguigu.gulimall.ware.vo.PurchaseDoneDetailVo;
import com.atguigu.gulimall.ware.vo.PurchaseDoneVo;
import com.atguigu.gulimall.ware.vo.PurchaseVo;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.ware.dao.PurchaseDao;
import com.atguigu.gulimall.ware.entity.PurchaseEntity;
import com.atguigu.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {
    @Autowired
    private PurchaseDetailService purchaseDetailService;
    @Autowired
    private WareSkuDao wareSkuDao;
    @Autowired
    private WareSkuService wareSkuService;
    @Autowired
    private ProductServiceFeign productServiceFeign;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();
        String status = (String) params.get("status");
        if (StringUtils.isNotBlank(status)) {
            wrapper.eq("status", status);
        }
        String key = (String) params.get("key");
        if (StringUtils.isNotBlank(key)) {
            wrapper.and(w -> w.eq("assignee_id", key).or().eq("id", key).or().like("assignee_name", key));
        }
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageUnreceivePurchase(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>().eq("status", 0).or().eq("status", 1)
        );
        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void mergePurchase(PurchaseVo vo) {
        //如果没有选择采购单则创建一个新的采购单
        Long purchaseId = vo.getPurchaseId();
        if (purchaseId == null) {
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setStatus(WareConstant.PurchaseStatus.NEW.getCode());
            purchaseEntity.setCreateTime(new Date());
            purchaseEntity.setUpdateTime(new Date());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }
        Long finalPurchaseId = purchaseId;
        List<Long> items = vo.getItems();
        List<PurchaseDetailEntity> collect = items.stream()
                .filter(id -> {
                    PurchaseDetailEntity entity = purchaseDetailService.getById(id);
                    return WareConstant.PurchaseDetailStatus.NEW.getCode().equals(entity.getStatus()) ||
                            WareConstant.PurchaseDetailStatus.ASSIGNED.getCode().equals(entity.getStatus());
                })
                .map(id -> {
                    PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                    purchaseDetailEntity.setPurchaseId(finalPurchaseId);
                    purchaseDetailEntity.setId(id);
                    purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatus.ASSIGNED.getCode());
                    return purchaseDetailEntity;
                }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(collect);
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(purchaseId);
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
    }

    @Override
    public void received(List<Long> ids) {
        // 查询过滤出所有新建或已分配的采购单更新采购订单的状态
        List<PurchaseEntity> collect = ids.stream()
                .map(id -> baseMapper.selectById(id)).filter(item -> WareConstant.PurchaseStatus.NEW.getCode().equals(item.getStatus()) ||
                        WareConstant.PurchaseStatus.ASSIGNED.getCode().equals(item.getStatus()))
                .peek(item -> {
                    item.setStatus(WareConstant.PurchaseStatus.RECEIVED.getCode());
                    item.setUpdateTime(new Date());
                })
                .collect(Collectors.toList());
        this.updateBatchById(collect);
        // 更新采购需求的状态
        collect.forEach(entity -> purchaseDetailService.updateStatusByPurchaseId(entity.getId(), WareConstant.PurchaseDetailStatus.BAYING.getCode()));
    }

    @Transactional
    @Override
    public void done(PurchaseDoneVo doneVo) {
        boolean flag = true;
        //改变采购项的状态
        ArrayList<PurchaseDetailEntity> updateDetails = new ArrayList<>();
        List<PurchaseDoneDetailVo> items = doneVo.getItems();
        for (PurchaseDoneDetailVo detailVo : items) {
            PurchaseDetailEntity entity = new PurchaseDetailEntity();
            entity.setId(detailVo.getItemId());
            entity.setStatus(detailVo.getStatus());
            updateDetails.add(entity);
            if (WareConstant.PurchaseDetailStatus.UNUSUAL.getCode().equals(detailVo.getStatus())) {
                flag = false;
            }
            if (WareConstant.PurchaseDetailStatus.DONE.getCode().equals(detailVo.getStatus())) {
                //将成功采购的进行入库
                PurchaseDetailEntity detailEntity = purchaseDetailService.getById(detailVo.getItemId());
                wareSkuService.addStock(detailEntity.getSkuId(),detailEntity.getWareId(),detailEntity.getSkuNum());
            }
        }
        purchaseDetailService.updateBatchById(updateDetails);
        //改变采购单的状态
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(doneVo.getId());
        purchaseEntity.setStatus(flag?WareConstant.PurchaseStatus.DONE.getCode():WareConstant.PurchaseStatus.UNUSUAL.getCode());
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
    }
}